package org.jrpc.client3;

import org.jrpc.base.*;
import org.jrpc.common.baen.RpcRequest;
import org.jrpc.common.registry.Constant;

import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by chenyuncong on 2019/4/24.
 */
public class JrpcClientManage implements IClientManage {
    // n,serviceName->{{1,serviceInfo},{2,serviceInfo}}
    private final Map<String, IClient> clientMap = new ConcurrentHashMap<>();
    private final Map<String, IClient> downClientMap = new ConcurrentHashMap<>();
    private final Random random = new Random();

    private ServiceInfoManage serviceInfoManage;

    public JrpcClientManage(ServiceInfoManage serviceInfoManage) {
        this.serviceInfoManage = serviceInfoManage;
    }

    private IClient getClient() {
//        serviceInfoManage
        return null;
    }

    @Override
    public ResultResponse put(String serviceName, RpcRequest request) {
//        clientMap.get(serviceName);
        List<ServiceInfo> list = serviceInfoManage.getServiceInfoByServiceName(serviceName);
        //负载 算法还没实现，目前就使用了一个简单的随机
        ServiceInfo serviceInfo = list.get(random.nextInt(list.size()));
        IClient iClient = clientMap.get(serviceInfo.getId());
        return iClient.put(request);
    }

    @Override
    public void addClient(ServiceInfo serviceInfo, IClient client) {
        if (!clientMap.containsKey(serviceInfo.getId()) && !downClientMap.containsKey(serviceInfo.getId())) {
            serviceMove(serviceInfo, client);
        }
    }

    /**
     * @param serviceInfo
     * @param client
     */
    private synchronized void serviceMove(ServiceInfo serviceInfo, IClient client) {
        switch (serviceInfo.getStatus()) {
            case Constant.UP:
                clientMap.put(serviceInfo.getId(), client);
                break;
            case Constant.DOWN:
                downClientMap.put(serviceInfo.getId(), client);
                break;
        }
    }

    @Override
    public void delClient(ServiceInfo serviceInfo) {
        //这种处理方式不好,代码还是多此一举的
        if (clientMap.containsKey(serviceInfo.getId())) {
            //出坑，标记成删除对象 先移动到 downClientMap 集合，
            IClient iClient = clientMap.remove(serviceInfo.getId());
        }
        //移动到任务监控队列中去，在任务中判断是否还有请求，没请求就关闭远程连接
        if (downClientMap.containsKey(serviceInfo.getId())) {
            downClientMap.remove(serviceInfo.getId());
        }
    }

    @Override
    public synchronized void clientUP(ServiceInfo serviceInfo) {
        if(serviceInfo.getStatus().equals(Constant.DOWN)){
            String serviceId=serviceInfo.getId();
            if (downClientMap.containsKey(serviceId)) {
                IClient iClient = downClientMap.remove(serviceId);
                clientMap.put(serviceId, iClient);
            }
        }
    }

    @Override
    public synchronized void clientDOWN(ServiceInfo serviceInfo) {
        if (serviceInfo.getStatus().equals(Constant.UP)) {
            String serviceId=serviceInfo.getId();
            if (clientMap.containsKey(serviceId)) {
                IClient iClient = clientMap.remove(serviceId);
                downClientMap.put(serviceId, iClient);
            }
        }
    }


}
